#include "animation.h"
#include "system.h"

#include "lualib.h"
#include "lua.h"
#include "lauxlib.h"

#include <string.h>
#include <stdio.h>
#include <memory.h>
#include <stdlib.h>

extern lua_State* g_ufo_lua_state;

static int lua_ufoAnimationCreate(lua_State *L)
{
	UFO_View view = *(UFO_View*)lua_touserdata(L, -1);
	UFO_Animation animation = ufoAnimationCreate(view);
	
    *(void**)lua_newuserdata(g_ufo_lua_state,sizeof(void*)) = animation;
    
	luaL_getmetatable(L, "ufo.ufoAnimation");
	lua_setmetatable(L, -2);
    
    ufoLog("lua", "lua_ufoAnimationCreate");

	return 1;
}

static int lua_ufoAnimationSetToValue(lua_State *L)
{
	UFO_Animation animation = *(UFO_Animation*)luaL_checkudata(L, 1, "ufo.ufoAnimation");
	
	const char *toValue = lua_tostring(L, 2);
	
	const char* rect = strstr(toValue, "rect");
	const char* alpha = strstr(toValue, "alpha");
	const char* angle = strstr(toValue, "angle");
	const char* z = strstr(toValue, "axisZ");
    
	UFO_Animation_Value value = {0};

	if (rect) {
		sscanf(rect, "rect(%f, %f, %f, %f)", &value.rect.left, &value.rect.top, 
			&value.rect.right, &value.rect.bottom);
		value.type |= Animation_rect;
	}

	if (alpha) {
		sscanf(alpha, "alpha(%f)", &value.alpha);
		value.type |= Animation_alpha;
	}

	if (angle) {
		sscanf(angle, "angle(%f)", &value.angle);
		value.type |= Animation_angle;
	}
    
	if (z) {
		sscanf(z, "axisZ(%f)", &value.z);
		value.type |= Animation_axisZ;
	}

	lua_pushinteger(L, ufoAnimationSetToValue(animation, value));

	return 1;
}

static int lua_ufoAnimationSetDuration(lua_State *L)
{
	UFO_Animation animation = *(UFO_Animation*)luaL_checkudata(L, 1, "ufo.ufoAnimation");
	int duration = (int)lua_tonumber(L, 2);
	ufoAnimationSetDuration(animation, duration);
	return 1;
}

static int lua_ufoAnimationSetRepeatTime(lua_State *L)
{
	UFO_Animation animation = *(UFO_Animation*)luaL_checkudata(L, 1, "ufo.ufoAnimation");
	int repeatTime = (int)lua_tonumber(L, 2);
	lua_pushinteger(L, ufoAnimationSetRepeatTime(animation, repeatTime));
	return 1;
}

static int lua_ufoAnimationSetDelay(lua_State *L)
{
	UFO_Animation animation = *(UFO_Animation*)luaL_checkudata(L, 1, "ufo.ufoAnimation");
	int delay = (int)lua_tonumber(L, 2);
	lua_pushinteger(L, ufoAnimationSetDelay(animation, delay));
	return 1;
}

static int lua_ufoAnimationSetAutoReverses(lua_State *L)
{
	UFO_Animation animation = *(UFO_Animation*)luaL_checkudata(L, 1, "ufo.ufoAnimation");
	int bRever = lua_toboolean(L, 2);
	lua_pushinteger(L, ufoAnimationSetAutoreverses(animation, bRever));
	return 1;
}

static int lua_ufoAnimationSetTimingFunction(lua_State *L)
{
	UFO_Animation animation = *(UFO_Animation*)luaL_checkudata(L, 1, "ufo.ufoAnimation");
	const char *timing = lua_tostring(L, 2);
    
    if (strcmp(timing, "TimingFunctionEaseInEaseOut") == 0) {
        ufoAnimationSetTimingFunction(animation, TimingFunctionEaseInEaseOut);
    }

    lua_pushinteger(L, 1);
	//ufoAnimationSetTimingFunction(animation, bRever);
	return 1;
}

static int lua_ufoAnimationPlay(lua_State *L)
{
	UFO_Animation animation = *(UFO_Animation*)luaL_checkudata(L, 1, "ufo.ufoAnimation");
	lua_pushinteger(L, ufoAnimationPlay(animation));
    ufoLog("lua", "lua_ufoAnimationPlay");
	return 1;
}

static int lua_ufoAnimationStop(lua_State *L)
{
	UFO_Animation animation = *(UFO_Animation*)luaL_checkudata(L, 1, "ufo.ufoAnimation");
	lua_pushinteger(L, ufoAnimationStop(animation));
	return 1;
}

static int lua_ufoAnimationGc(lua_State *L)
{
	UFO_Animation animation = *(UFO_Animation*)luaL_checkudata(L, 1, "ufo.ufoAnimation");
	int a = 0;
    int b = 0;
    a = b;
	return 0;
}

static const struct luaL_Reg animationlib_c [] = {
	{"create", lua_ufoAnimationCreate},
	{0, 0},
};

static const struct luaL_Reg animationlib [] = {
	{"setDuration", lua_ufoAnimationSetDuration},
	{"setDelay", lua_ufoAnimationSetDelay},
	{"setToValue", lua_ufoAnimationSetDelay},
	{"setAutoReverses", lua_ufoAnimationSetAutoReverses},
	{"setTimingFunction", lua_ufoAnimationSetTimingFunction},
	{"setToValue", lua_ufoAnimationSetToValue},
	{"setRepeatTime", lua_ufoAnimationSetRepeatTime},
	{"play", lua_ufoAnimationPlay},
	{"stop", lua_ufoAnimationStop},
    {"__gc", lua_ufoAnimationGc},
	{0, 0},
};

int internal_initializationScript_animation()
{
	if (!g_ufo_lua_state) {
		g_ufo_lua_state = luaL_newstate();
		luaL_openlibs(g_ufo_lua_state);
	}

	luaL_newmetatable(g_ufo_lua_state, "ufo.ufoAnimation");

	lua_pushvalue(g_ufo_lua_state, -1);
	lua_setfield(g_ufo_lua_state, -2, "__index");

	luaL_register(g_ufo_lua_state, 0, animationlib);
	luaL_register(g_ufo_lua_state, "ufoAnimation", animationlib_c);

	return 1;
}